package com.service.business.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.beust.jcommander.internal.Lists;
import com.service.business.merchant.controller.rep.CommodityPriceRep;
import com.service.business.merchant.controller.req.CommodityPriceAddReq;
import com.service.business.merchant.service.MerchantCommodityPriceService;
import com.service.business.support.Language;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.CommonStatusEnums;
import com.service.dao.enums.LanguageEnum;
import com.service.dao.model.MerchantCommodityPrice;
import com.service.utility.modelmapper.ModelMapperUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.service.dao.mapper.MerchantCommodityPriceMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


@Service("merchantCommodityPriceService")
public class MerchantCommodityPriceServiceImpl extends ServiceImpl<MerchantCommodityPriceMapper, MerchantCommodityPrice> implements MerchantCommodityPriceService {

    @Override
    public MerchantCommodityPrice getCommodityPrice(Integer commodityId, String language) {
        Map<String, MerchantCommodityPrice> priceMap = list(new QueryWrapper<MerchantCommodityPrice>().lambda()
                .eq(MerchantCommodityPrice::getCommodityId, commodityId)
                .eq(MerchantCommodityPrice::getPriceStatus, CommonStatusEnums.ACTIVE.getCode()))
                .parallelStream()
                .collect(Collectors.toMap(MerchantCommodityPrice::getCoinsName, item -> item));

        CoinsEnum coins = StringUtils.endsWithIgnoreCase(language, LanguageEnum.zh_CN.getCode()) ? CoinsEnum.CNY : CoinsEnum.USDT;
        return priceMap.containsKey(coins.getName()) ? priceMap.get(coins.getName()) : priceMap.get(CoinsEnum.CNY.getName());
    }

    @Override
    public Map<String, CommodityPriceRep> getCommodityPrice2Map(Integer commodityId) {
        return listPrice(commodityId).parallelStream()
                .collect(Collectors.toMap(MerchantCommodityPrice::getLocalLanguage, item -> ModelMapperUtil.map(item, CommodityPriceRep.class)));
    }

    @Override
    public Map<String, BigDecimal> getCommodityPrice2CoinKeyMap(Integer commodityId) {
        return listPrice(commodityId).parallelStream()
                .collect(Collectors.toMap(MerchantCommodityPrice::getCoinsName, MerchantCommodityPrice::getPrice));
    }

    @Override
    public List<CommodityPriceRep> getCommodityPrice2List(Integer commodityId) {
        return listPrice(commodityId).stream()
                .map(item -> ModelMapperUtil.map(item, CommodityPriceRep.class))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCommodityPrice(Integer commodityId, List<CommodityPriceAddReq> priceAddReqs) {
        Date currentData = new Date();
        List<MerchantCommodityPrice> prices = priceAddReqs.stream().map(item -> {
            MerchantCommodityPrice resultItem = ModelMapperUtil.map(item, MerchantCommodityPrice.class);
            resultItem.setCoinsId(item.getCoin().getCode());
            resultItem.setCoinsName(item.getCoin().getName());
            resultItem.setCommodityId(commodityId);
            resultItem.setCreateTime(currentData);
            return resultItem;
        }).collect(Collectors.toList());

        saveBatch(prices);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCommodityPrice(Integer commodityId, List<CommodityPriceAddReq> priceAddReqs) {

        List<MerchantCommodityPrice> pricesList = listPrice(commodityId);
        if (!ObjectUtils.isEmpty(pricesList)) {
            this.updateBatchById(pricesList.parallelStream()
                    .map(item -> MerchantCommodityPrice.builder()
                            .id(item.getId())
                            .priceStatus(CommonStatusEnums.INVALID.getCode()).build())
                    .collect(Collectors.toList()));
        }
        saveCommodityPrice(commodityId, priceAddReqs);

    }

    private List<MerchantCommodityPrice> listPrice(Integer commodityId) {
        return list(new QueryWrapper<MerchantCommodityPrice>().lambda()
                .eq(MerchantCommodityPrice::getCommodityId, commodityId)
                .eq(MerchantCommodityPrice::getPriceStatus, CommonStatusEnums.ACTIVE.getCode())
                .orderByAsc(MerchantCommodityPrice::getId));
    }

    public MerchantCommodityPrice getByCoinNameAndCommodityId(Integer commodityId, String coinName) {
        return getOne(new QueryWrapper<MerchantCommodityPrice>().lambda()
                .eq(MerchantCommodityPrice::getCommodityId, commodityId)
                .eq(MerchantCommodityPrice::getCoinsName, coinName)
                .eq(MerchantCommodityPrice::getPriceStatus, CommonStatusEnums.ACTIVE.getCode()));
    }

}
